<!DOCTYPE HTML>
<html>
<head>
<title>RegExMatch() | AutoHotkey</title>
<meta name="description" content="The RegExMatch function determines whether a string contains a pattern (regular expression)." />
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>RegExMatch() <span class="ver">[v1.0.45+]</span></h1>

<p>判断字符串是否包含某个匹配模式(正则表达式).</p>

<pre class="Syntax">FoundPos := <span class="func">RegExMatch</span>(Haystack, NeedleRegEx <span class="optional">, OutputVar, StartingPosition := 1</span>)</pre>
<h2>参数</h2>
<dl>

  <dt>Haystack</dt>
  <dd><p>源字符串.</p></dd>

  <dt>NeedleRegEx</dt>
  <dd><p>要搜索的模式, 它是兼容 Perl 的正则表达式(PCRE). 模式的<a href="../misc/RegEx-QuickRef.htm#Options">选项</a>(如果有) 必须放在模式字符串的开始且后面跟着闭括号. 例如, 模式 "<span class="red">i)</span>abc.*123" 将匹配不区分大小写的 "abc", 接着零个或多个任意字符, 并以 "123" 结尾的字符串. 如果不含选项, 则可以省略 ")"; 例如, ")abc" 等同于 "abc".</p></dd>

  <dt>OutputVar</dt>
  <dd><p><strong>模式 1(默认):</strong> 指定一个变量, 用来保存与整个模式匹配的 <em>Haystack</em> 的部分. 如果没有找到模式(即如果函数返回 0), 则此变量和下面的所有数组元素都被置空.</p>
      <p id="Array">如果在 <em>NeedleRegEx</em> 中包含<a href="../misc/RegEx-QuickRef.htm#subpat">捕获子模式</a>, 那么它们的匹配将被存储在基名称为 <em>OutputVar</em> 的<a href="../misc/Arrays.htm#pseudo">伪数组</a>里. 例如, 如果输出变量名是 <em>Match</em>, 则匹配首个子模式的子字符串存储在 <em>Match1</em>, 第二个存储在 <em>Match2</em>, 依此类推. 这种情况的例外是<a href="#NamedSubPat">命名子模式</a>: 它们以名称而不是数字保存. 例如, 匹配命名子模式"(?P&lt;Year&gt;\d{4})"的子字符串存储在 <em>MatchYear</em>. 如果特定的子模式不匹配任何文本(或如果函数返回零), 则相应的变量被置空.</p>
      <p>在<a href="Functions.htm">函数</a>中, 要创建全局而不是局部的伪数组, 则必须在使用前<a href="../Functions.htm#Global">声明</a>伪数组的基名称(例如 Match) 为全局变量. 对于<a href="../Functions.htm#AssumeGlobal">假设全局</a>函数, 反之亦成. 但是, 通常需要对每个变量都进行声明, 因为可能会造成<a href="../Functions.htm#ArrayConfusion">混乱的根源</a>.</p>
      <p id="PosMode"><strong>模式 2(位置和长度):</strong> 如果在正则表达式选项中含有 P(例如 "<span class="red">P)</span>abc.*123"), 则整个模式的匹配字符串的 <em>长度</em> 会被存储到 <em>OutputVar</em>(如果没有匹配则为 0). 如果包含<a href="../misc/RegEx-QuickRef.htm#subpat">捕获子模式</a>, 则它们匹配的位置和长度会被存储到两个<a href="../misc/Arrays.htm#pseudo">伪数组</a>: <em>OutputVarPos</em> 和 <em>OutputVarLen</em>. 例如, 如果变量的基名称为 <em>Match</em>, 首个子模式的匹配<em>位置</em>(基于 1) 会存储在 <em>MatchPos1</em>, 而它的长度存储在 <em>MatchLen1</em>(如果子模式没有匹配或函数返回 0 则它们两者中保存的都为零). 这种情况的例外是<a href="#NamedSubPat">命名子模式</a>: 它们以名称而不是数字保存(例如 <em>MatchPosYear</em> 和 <em>MatchLenYear</em>).</p>
      <p id="ObjectMode"><strong>模式 3(匹配对象)</strong> <span class="ver">[v1.1.05+]</span><strong>:</strong> 如果在正则表达式选项中含有大写的 O(例如 "<span class="red">O)</span>abc.*123"), 则<a href="#MatchObject">匹配对象</a>会被存储到 <em>OutputVar</em>. 此对象还可以用来获取整个匹配和每个<a href="../misc/RegEx-QuickRef.htm#subpat">捕获子模式</a>(如果存在) 的位置, 长度和值.</p>
    </dd>

  <dt>StartingPosition</dt>
  <dd><p>如果省略 <em>StartingPosition</em>, 则它默认为 1(从 <em>Haystack</em> 的首个字符开始). 否则, 从第二个字符开始请指定 2, 第三个开始为 3, 依此类推. 如果 <em>StartingPosition</em> 超过了 <em>Haystack</em> 的长度, 则搜索会从 <em>Haystack</em> 末尾后的空字符串开始(这通常会导致没有匹配发生).</p>
      <p>如果 <em>StartingPosition</em> 小于 1, 则它被视为从 <em>Haystack</em> 末尾开始的偏移. 例如, 0 表示从最后一个字符开始, 而 -1 则从倒数第二个字符开始. 如果 <em>StartingPosition</em> 超出了 <em>Haystack</em> 最左边的位置, 则会搜索整个 <em>Haystack</em>.</p>
      <p>不论 <em>StartingPosition</em> 的值是多少, 返回的值总是相对于 <em>Haystack</em> 的第一个字符. 例如, "abc" 在 "123abc789" 中的位置总是 4.</p></dd>

</dl>

<h2>返回值</h2>
<p>函数返回在字符串 <em>Haystack</em> 中最左边出现 <em>NeedleRegEx</em> 的位置. 位置 1 表示第一个字符. 0 表示没有找到匹配. 如果发生错误(比如 <em>NeedleRegEx</em> 出现语法错误), 将返回空字符串同时 ErrorLevel 被设为<a href="#ErrorLevel">下面</a>列表中除了 0 之外的值.</p>

<h2 id="ErrorLevel">错误处理</h2>
<p><span class="ver">[v1.1.04+]</span>: 此函数失败时会抛出异常(这个不会和 "没有找到匹配" 冲突, 失败表示匹配过程中遇到问题, 而 "没有找到匹配" 表示匹配过程成功完成只是没有发现匹配). 想了解更多信息, 请参阅<a href="Catch.htm#RuntimeErrors">运行时错误</a>.</p>
<p><a href="../misc/ErrorLevel.htm">ErrorLevel</a> 被设置为下列值的其中一个:</p>
<ul>
  <li>0, 表示没有遇到错误.</li>
  <li>一个如下格式的字符串: <em>Compile error N at offset M: description</em>. 在此字符串中, <em>N</em> 是 PCRE 错误值, <em>M</em> 是正则表达式中出现错误的字符的位置, 而 <em>description</em> 是描述这个错误的文本.</li>
  <li>一个负数, 表示在正则表达式 <em>执行</em> 时遇到的错误. 尽管这样的错误很罕见, 然而像这些情况就容易出现这种错误, 例如 "太多空字符串匹配"(-22), "递归太深"(-21) 以及 "达到匹配限制"(-8). 如果出现这些情况, 请尝试重新设计更严格的匹配模式, 例如无论是否可行都把每个 * 替换为 ?, + 或像 {0,3} 这样的限制.</li>
</ul>
<h2>选项</h2>
<p>请参阅<a href="../misc/RegEx-QuickRef.htm#Options">选项</a>了解修饰符, 例如 "<span class="red">i)</span>abc", 里面的选项关闭了 "abc" 模式中的区分大小写匹配.</p>
<h2 id="MatchObject">匹配对象 <span class="ver">[v1.1.05+]</span></h2>
<p>如果在正则表达式选项中含有大写的 O, 则匹配对象会被存储到 <em>OutputVar</em>. 此对象含有下列属性:</p>
<p><strong>Match.Pos(N)</strong>: 返回整个匹配或捕获子模式的位置.</p>
<p><strong>Match.Len(N)</strong>: 返回整个匹配或捕获子模式的长度.</p>
<p><strong>Match.Value(N)</strong>: 返回整个匹配或捕获子模式.</p>
<p><strong>Match.Name(N)</strong>: 返回指定的子模式的名称(如果它含有).</p>
<p><strong>Match.Count()</strong>: 返回所有子模式的数目.</p>
<p><strong>Match.Mark()</strong>: 适用时返回上次遇到 <code>(*MARK:NAME)</code> 的 <em>NAME</em>.</p>
<p><strong>Match[N]</strong>: 如果 <em>N</em> 为 0 或有效的子模式编号或名称, 那么它相当于 <code>Match.Value(N)</code>. 否则, <em>N</em> 可以为上面其中一个属性的名称. 例如, <code>Match["Pos"]</code> 和 <code>Match.Pos</code> 相当于 <code>Match.Pos()</code>, 不过如果存在名称为 "Pos" 的子模式, 此时它们相当于 <code>Match.Value("Pos")</code>.</p>
<p><strong>Match.N</strong>: 与上面相同, 不过这里 <em>N</em> 为未引用的名称或编号.</p>
<p>对于上面的所有属性, 其中 <em>N</em> 可以为下列值:</p>
<ul>
  <li>0 表示整个匹配.</li>
  <li>子模式的编号, 包括含有名称的子模式.</li>
  <li>子模式的名称.</li>
</ul>
<p>如果指定了 <em>N</em>, 则可以使用方括号 [] 代替其中的圆括号.</p>

<h2>性能</h2>
<p>要在一个较大的字符串中搜索简单的子字符串, 请使用 <a href="InStr.htm">InStr()</a> 因为它比 RegExMatch() 更快.</p>
<p>为了提升性能, 最近使用的 100 个正则表达式会被缓存在内存中(以已编译的形式).</p>
<p>多次使用一个正则表达式时(例如在循环中), 使用<a href="../misc/RegEx-QuickRef.htm#Study">研究选项(S)</a> 可以提高性能.</p>
<h2>备注</h2>
<p id="NamedSubPat">可以为子模式指定名称, 例如模式"(?P&lt;Year&gt;\d{4})"中的 <em>Year</em>. 这种名称最多可以由 32 个字母数字和下划线组成. 下面的限制不适用于"O"(匹配对象) 模式:尽管命名的子模式在正则表达式运算时还可以使用它们的编号(例如 \1 为到实际匹配首个捕获子模式的字符串的后向引用), 然而它们被存储到<a href="#Array">输出伪数组</a>时<em>只</em>通过名称(而不是编号). 例如, 如果"Year"是首个子模式, 则 <em>OutputVarYear</em> 会被设置为匹配的子字符串, 但 <em>OutputVar1</em> 不会发生变化(如果有则它会保持原来的值). 然而, 如果在"Year"后含有<a href="../misc/RegEx-QuickRef.htm#subpat">未命名子模式</a>, 则它会被存储到 <em>OutputVar2</em>, 而不是 <em>OutputVar1</em>.</p>
<p>大多数字符(例如 abc123) 可以直接使用在正则表达式中. 然而, <strong>\.*?+[{|()^$</strong> 这些字符则必须在其前面加上反斜杠来进行匹配. 例如, <strong>\.</strong> 表示一个原义的句点而 <strong>\\</strong> 表示一个原义的反斜杠. 使用 \Q...\E 能避免转义. 例如: <code>\QLiteral Text\E</code>.</p>
<p>在正则表达式中, 特殊字符(如制表符和换行符) 可以使用一个重音符(`) 或反斜杠(\) 进行转义. 例如, 不含 <b>x</b> 选项时 `t 等同于 \t.</p>
<p>要了解正则表达式的基础(或复习正则表达式的语法), 请参阅<a href="../misc/RegEx-QuickRef.htm">正则表达式快速参考</a>.</p>
<p>AutoHotkey 的正则表达式是使用来自 <a href="http://www.pcre.org/">www.pcre.org</a> 的兼容 Perl 的正则表达式(PCRE) 实现的.</p>
<p><span class="ver">[AHK_L 31+]:</span> 在<a href="../Variables.htm#Expressions">表达式</a>中, <code>a <a href="../Variables.htm#regex">~=</a> b</code> 能被当作 <code>RegExMatch(a, b)</code> 的缩写.</p>
<h2>相关</h2>
<p><a href="RegExReplace.htm">RegExReplace()</a>, <a href="../misc/RegEx-QuickRef.htm">正则表达式快速参考</a>, <a href="../misc/RegExCallout.htm">正则表达式调出</a>, <a href="InStr.htm">InStr()</a>, <a href="IfInString.htm">IfInString</a>, <a href="StringGetPos.htm">StringGetPos</a>, <a href="SubStr.htm">SubStr()</a>, <a href="SetTitleMatchMode.htm#RegEx">SetTitleMatchMode RegEx</a>, <a href="https://www.autohotkey.com/forum/topic16164.html">全局匹配和 Grep(论坛链接)</a></p>
<p>文本数据的常见来源: <a href="FileRead.htm">FileRead</a>, <a href="URLDownloadToFile.htm">UrlDownloadToFile</a>, <a href="../misc/Clipboard.htm">Clipboard</a>, <a href="GuiControls.htm#Edit">GUI Edit 控件</a></p>
<h2>示例</h2>
<p>有关普通 RegEx 的示例, 请参阅<a href="../misc/RegEx-QuickRef.htm">正则表达式快速参考</a>.</p>

<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a></p>
<pre>MsgBox % RegExMatch(&quot;xxxabc123xyz&quot;, &quot;abc.*xyz&quot;)  <em>; 显示 4, 这是找到匹配的位置.</em>
MsgBox % RegExMatch(&quot;abc123123&quot;, &quot;123$&quot;)  <em>; 显示 7, 因为 $ 要求在末端进行匹配.</em>
MsgBox % RegExMatch(&quot;abc123&quot;, &quot;i)^ABC&quot;)  <em>; 显示 1, 因为通过不区分大小写选项实现了匹配.</em>
MsgBox % RegExMatch(&quot;abcXYZ123&quot;, &quot;abc(.*)123&quot;, SubPat)  <em>; 显示 1, 并把 "XYZ" 保存到 SubPat1.</em>
MsgBox % RegExMatch(&quot;abc123abc456&quot;, &quot;abc\d+&quot;, &quot;&quot;, 2)  <em>; 显示 7 而不是 1, 这是由于 StartingPosition 为 2 而不是 1.</em></pre>
</div>

<div class="ex" id="ExObject">
<p><a href="#ExObject">#2</a>: 匹配对象</p>
<pre>FoundPos := RegExMatch(&quot;Michiganroad 72&quot;, &quot;O)(.*) (?&lt;nr&gt;\d+)&quot;, SubPat)  <em>; 开始的 "O)" 将 SubPat 变成一个对象.</em>
Msgbox % SubPat.Count() ": " SubPat.Value(1) " " SubPat.Name(2) "=" SubPat["nr"]  <em>; 显示 "2: Michiganroad nr=72"</em></pre>
</pre>
</div>

<div class="ex" id="ExExtension">
<p><a href="#ExExtension">#3</a>: 一个检索文件扩展名的简单示例. 注意 <a href="SplitPath.htm">SplitPath</a> 也可以用于此目的, 而这更可靠.</p>
<pre>Path := "C:\Foo\Bar\Baz.txt"
RegExMatch(Path, "\w+$", Extension)
MsgBox % Extension  <em>; 显示 "txt".</em></pre>
</div>

</body>
</html>